package pl.lodz.p.services;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import org.hibernate.type.YesNoType;

import pl.lodz.p.beans.utils.HibernateUtil;
import pl.lodz.p.model.Doctor;
import pl.lodz.p.model.Schedule;
import pl.lodz.p.model.Visit;
import pl.lodz.p.model.enums.Specialization;

public class VisitServiceImpl implements VisitService {

	public List<Visit> getVisits(Date fromDate, Date endDate, List<Doctor> doctor) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		List<Visit> visits = session.createCriteria(Schedule.class)
			.add(Restrictions.ge("dateStart", fromDate))
			.add(Restrictions.le("dateEnd", endDate))
			.add(Restrictions.in("doctor", doctor))
			.list();
		
		
		return visits;
	}

	public List<Visit> getFree(Doctor doctor) {
		List<Visit> result = new ArrayList<Visit>();
		for (Schedule schedule : doctor.getSchedules()) {
			for (Visit visit : schedule.getVisits()) {
				if (visit.getPatient() != null){
					if (visit.getDetails() == null || visit.getDetails().getDescritpion() == null){
						result.add(visit);
					}
				}
			}
		}
		return result;
	}

	public List<Visit> findByFilter(Specialization specialization,
			Date dateStart, Date dateEnd, List<Doctor> doctors) {
		if (dateStart == null || dateStart.before(new Date())){
			dateStart = new Date();
		}
		if (dateEnd == null || dateEnd.before(new Date())){
			Calendar c = Calendar.getInstance();
			c.add(Calendar.MONTH, 3);
			dateEnd = c.getTime();
		}
		List<Specialization> specs;
		if (specialization == null){
			specs = new ArrayList<Specialization>(Arrays.asList(Specialization.values()));
		} else {
			specs = new ArrayList<Specialization>();
			specs.add(specialization);
		}
		Session session = HibernateUtil.getSessionFactory().openSession();
		List<Schedule> schedules = new ArrayList<Schedule>();
		List<Visit> visits = new ArrayList<Visit>();
		if (doctors != null && doctors.size() > 0){
			schedules = session.createCriteria(Schedule.class)
				.add(Restrictions.in("doctor", doctors))
				.list();
		} else {
			doctors = session.createCriteria(Doctor.class)
				.add(Restrictions.in("spec", specs))
				.list();
			if (doctors.isEmpty()){
				return Collections.emptyList();
			}
			schedules = session.createCriteria(Schedule.class)
				.add(Restrictions.in("doctor", doctors))
				.list();
		}
		if (schedules.isEmpty()){
			return Collections.emptyList();
		}
		visits = session.createCriteria(Visit.class)
			.add(Restrictions.in("schedule", schedules))
			.add(Restrictions.ge("dateStart", dateStart))
			.add(Restrictions.lt("dateStart", dateEnd))
			.add(Restrictions.isNull("patient"))
			.list();
		
		session.close();
		return visits;
	}

	public String saveOrUpdateVisit(Visit v) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			session.saveOrUpdate(v);
			tx.commit(); 
			return "saved";
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
				e.printStackTrace();
				return "error";
			}
		} finally {
			session.close();
		}
		return "error";
	}

}
